﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpShare.Storage;
using SharpShare.Diagnostics;
using SharpShare.Storage.Security;

namespace SharpShare.Afp.Protocol.Handlers {
    internal class AfpOpenForkRequestHandler : IAfpRequestHandler, ILogProvider {
        #region IAfpRequestHandler Members

        public byte CommandCode {
            get { return 26; }
        }

        public AfpResultCode Process(IAfpSession session, DsiHeader dsiHeader, AfpStream requestStream, AfpStream responseStream) {
            byte flag = requestStream.ReadUInt8();
            ushort volumeId = requestStream.ReadUInt16();
            uint directoryId = requestStream.ReadUInt32();

            bool resourceFork = (flag != 0);

            //if (resourceFork) {
            //    Log.Add(this, EntryType.Error, "Session '{0}' attempted to open resource fork, failing...", session);
            //    return AfpResultCode.FPMiscErr;
            //}

            AfpFileDirectoryBitmap bitmap = requestStream.ReadEnum<AfpFileDirectoryBitmap>();
            AfpAccessModes accessMode = requestStream.ReadEnum<AfpAccessModes>();
            IAfpVolume volume;
            IStorageFile file = requestStream.ReadPathAndFind(session, volumeId, directoryId, out volume).DemandFile();

            StorageAccessList access = file.GetEffectiveAccess(session);

            if (accessMode.HasFlag(AfpAccessModes.Read)) {
                access.DemandRight(StorageAccessRight.ReadData);
            }
            if (accessMode.HasFlag(AfpAccessModes.Write)) {
                access.DemandRight(StorageAccessRight.WriteData);
            }

            IAfpFork info = session.OpenFork(volume, file, accessMode, resourceFork);

            if (info == null) {
                throw new StorageItemNotFoundException();
            }

            responseStream.WriteEnum<AfpFileDirectoryBitmap>(bitmap);
            responseStream.WriteInt16(info.Identifier);

            if (bitmap != 0) {
                file.WriteStorageItemParameters(responseStream, volume, bitmap);
            }

            return AfpResultCode.FPNoErr;

        }

        #endregion

        string ILogProvider.Name {
            get { return "AFP Open Fork"; }
        }
    }
}
